package com.leinao.util;

import com.jcraft.jsch.*;
import com.leinao.task.ImageCallable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.backoff.Sleeper;
import org.springframework.stereotype.Component;

import java.io.*;

/**
 * @description: SSH登录
 * @author: 曹阳
 * @date: 2019-05-16 15:47
 */
@Component
public class SSHClient {
    private Logger logger = LoggerFactory.getLogger(SSHClient.class);

    /**
     * Server Host IP Address，default value is localhost
     */
    private String host = "localhost";

    /**
     * Server SSH Port，default value is 22
     */
    private Integer port = 22;

    /**
     * SSH Login Username
     */
    private String username = "";

    /**
     * SSH Login Password
     */
    private String password = "";

    /**
     * JSch
     */
    private JSch jsch = null;

    /**
     * ssh session
     */
    private Session session = null;

    /**
     * ssh channel
     */
    private Channel channel = null;

    /**
     * timeout for session connection
     */
    private final Integer SESSION_TIMEOUT = 30000;

    /**
     * timeout for channel connection
     */
    private final Integer CHANNEL_TIMEOUT = 30000;

    /**
     * the interval for acquiring ret
     */
    private final Integer CYCLE_TIME = 100;

    public SSHClient() {
        // initialize
        jsch = new JSch();
    }

    public SSHClient setHost(String host) {
        this.host = host;
        return this;
    }

    public SSHClient setPort(Integer port) {
        this.port = port;
        return this;
    }

    public SSHClient setUsername(String username) {
        this.username = username;
        return this;
    }

    public SSHClient setPassword(String password) {
        this.password = password;
        return this;
    }


    /**
     * login to server
     *
     * @param username
     * @param password
     */
    public void login(String username, String password) {

        this.username = username;
        this.password = password;

        try {
            if (null == session) {
                session = jsch.getSession(this.username, this.host, this.port);
                session.setPassword(this.password);
                java.util.Properties config = new java.util.Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config);
                session.setTimeout(1500);// 设置超时
                session.connect();
            }
        } catch (JSchException e) {
            logger.info("login JSchException", e);
            this.logout();
        }
    }

    public void connect(String user, String passwd, String host, int port) throws JSchException {
        jsch = new JSch();// 创建JSch对象
        session = jsch.getSession(user, host, port);// 根据用户名、主机ip、端口号获取一个Session对象
        session.setPassword(passwd);// 设置密码
        session.setConfig("StrictHostKeyChecking", "no");
        session.setTimeout(1500);// 设置超时
        session.connect();// 通过Session建立连接
    }

    /**
     * login to server
     */
    public void login() {
        this.login(this.username, this.password);
    }

    /**
     * logout of server
     */
    public void logout() {
        this.session.disconnect();
    }

    /**
     * send command through the ssh session,return the ret of the channel
     *
     * @return
     */
    public String sendCmd(String command) {
        if(session == null||!session.isConnected()){
            login();
        }
        StringBuffer result = new StringBuffer();
        BufferedReader reader = null;
        Channel channel = null;
        try {
            if (command != null) {
                channel = session.openChannel("exec");
                ((ChannelExec) channel).setPty(true);
                ((ChannelExec) channel).setCommand("sudo -S -p '' " + command);
                channel.connect();
                InputStream in = channel.getInputStream();
                OutputStream out=channel.getOutputStream();
                out.write((this.password + "\n").getBytes());
                out.flush();
                reader = new BufferedReader(new InputStreamReader(in));
                String buf = null;
                while ((buf = reader.readLine()) != null) {
                    result.append(buf);
                }
            }
        } catch (IOException e) {
            logger.info("sendCmd IOException", e);
        } catch (JSchException e) {
            logger.info("sendCmd JSchException", e);
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            channel.disconnect();
        }
        return result.toString();
    }


    public String runShell(String cmd) throws Exception {
        if(session == null||!session.isConnected()){
            login();
        }
        if(channel == null||!channel.isConnected()){
            channel = session.openChannel("shell");
            channel.connect(1000);
        }
        String temp = null;

        InputStream instream = null;
        OutputStream outstream = null;

        try {
            System.out.println("11111");
            instream = channel.getInputStream();
            outstream = channel.getOutputStream();
            outstream.write(cmd.getBytes());
            outstream.flush();
            System.in.read("root".getBytes());
            Thread.sleep(2000);
            if (instream.available() > 0) {
                System.out.println("22222");
                byte[] data = new byte[instream.available()];
                int nLen = instream.read(data);

                if (nLen < 0) {
                    throw new Exception("network error...桌面有错误");
                }
                temp = new String(data, 0, nLen, "UTF-8");
            }
        }  finally {
            outstream.close();
            instream.close();
        }
        return temp;
    }


    /**
     * customized userinfo
     */
    private static class MyUserInfo implements UserInfo {
        @Override
        public String getPassphrase() {
            return null;
        }

        @Override
        public String getPassword() {
            return null;
        }

        @Override
        public boolean promptPassword(String s) {
            return false;
        }

        @Override
        public boolean promptPassphrase(String s) {
            return false;
        }

        @Override
        public boolean promptYesNo(String s) {
            return true;
        }

        @Override
        public void showMessage(String s) {
            System.out.println("showMessage:" + s);
        }
    }
}